package GUI.main.dialogs;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;

import javax.swing.AbstractListModel;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JDialog;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ListModel;
import javax.swing.border.EmptyBorder;

import GUI.helpers.ButtonType;
import GUI.helpers.PButton;
import GUI.helpers.PTextField;
import GUI.helpers.ProjectConstants;
import GUI.helpers.TextFieldType;
import GUI.main.MainClient;
import GUI.main.renderers.AppointmentListRenderer;

import officeserver.log_error.UserException;
import officeserver.report.Appointment;
import officeserver.users.PersonalInfo;

/**
 * @author mramsey3
 * 
 */
public class UserProfile extends JDialog implements ActionListener {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    private JPanel topPanel;
    private JPanel mainPanel;
    private JPanel bottomPanel;

    private JPanel firstPanel;
    private JPanel lastPanel;
    private JPanel userPanel;
    private JPanel emailPanel;
    private JPanel phonePanel;
    private JPanel agePanel;

    private PTextField firstField;
    private PTextField lastField;
    private PTextField userField;
    private PTextField emailField;
    private PTextField phoneField;
    private PTextField ageField;

    private JPanel fPanel;
    private JPanel lPanel;
    private JPanel uPanel;
    private JPanel pPanel;
    private JPanel ePanel;
    private JPanel aPanel;

    private PButton firstEdit;
    private PButton lastEdit;
    private PButton userEdit;
    private PButton emailEdit;
    private PButton phoneEdit;
    private PButton ageEdit;

    private JPanel titlePanel;
    private JScrollPane appointmentScrollPane;
    private JList appointmentList;
    
    private JPanel buttonPanel;
    private PButton closeButton;

    public final static int WIDTH = 475;
    public final static int HEIGHT = 525;

    private PersonalInfo user;

    /**
     * @param user
     */
    public UserProfile(PersonalInfo user) {
	this.user = user;
	setSize(new Dimension(WIDTH, HEIGHT));
	setLayout(new BorderLayout());
	final Toolkit toolkit = Toolkit.getDefaultToolkit();
	final Dimension screenSize = toolkit.getScreenSize();
	final int x = (screenSize.width - WIDTH) / 2;
	final int y = (screenSize.height - HEIGHT) / 2;
	setLocation(x, y);
	add(getTopPanel(), BorderLayout.NORTH);
	add(getMainPanel(), BorderLayout.CENTER);
	add(getBottomPanel(), BorderLayout.SOUTH);
    }

    /**
     * @return
     */
    private JPanel getTopPanel() {
	if (topPanel == null) {
	    topPanel = new JPanel() {
		private static final long serialVersionUID = 1L;

		public void paintComponent(Graphics g) {
		    super.paintComponent(g);
		    g.setColor(ProjectConstants.SUBHEADER_COLOR);
		    g.fillRect(0, 0, getWidth(), getHeight());
		    g.setColor(Color.white);
		    g.setFont(new Font(Font.SANS_SERIF, Font.BOLD, 24));
		    g.drawString(user.getAccessLevel().toString().toLowerCase()
			    + ":" + user.getUsername().toUpperCase(), 24,
			    getHeight() - 8);
		}
	    };
	    topPanel.setPreferredSize(new Dimension(WIDTH, ProjectConstants.HEADER_HEIGHT));
	}
	return topPanel;
    }

    /**
     * @return
     */
    private JPanel getMainPanel() {
	if (mainPanel == null) {
	    mainPanel = new JPanel();

	    mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.PAGE_AXIS));

	    mainPanel.add(getFirstPanel());
	    mainPanel.add(getLastPanel());
	    mainPanel.add(getUserPanel());
	    mainPanel.add(getEmailPanel());
	    mainPanel.add(getPhonePanel());
	    mainPanel.add(getAgePanel());
	}
	return mainPanel;
    }

    /**
     * @return
     */
    private JPanel getFirstPanel() {
	if (firstPanel == null) {
	    firstPanel = new JPanel();
	    
	    firstPanel.setLayout(new BorderLayout());
	    firstPanel.setBorder(new EmptyBorder(10,10,0,10));

	    firstPanel.add(getFPanel(), BorderLayout.WEST);

	    JPanel centerPanel = new JPanel();
	    centerPanel.setLayout(new GridBagLayout());
	    GridBagConstraints gbc1 = new GridBagConstraints();
	    gbc1.anchor = GridBagConstraints.WEST;
	    gbc1.weightx = 1;
	    centerPanel.add(getFirstField(), gbc1);
	    firstPanel.add(centerPanel, BorderLayout.CENTER);

	    
	    firstPanel.add(getFirstEdit(), BorderLayout.EAST);
	}
	return firstPanel;
    }

    /**
     * @return
     */
    private JPanel getFPanel() {
	if (fPanel == null) {
	    fPanel = new JPanel() {
		private static final long serialVersionUID = 1L;

		public void paintComponent(Graphics g) {
		    super.paintComponent(g);
		    g.setColor(new Color(100, 150, 220));
		    g.fillRect(0, 0, getWidth(), getHeight());
		    g.setColor(Color.white);
		    g.setFont(new Font(Font.SANS_SERIF, Font.BOLD, 20));
		    g.drawString("f:", 5, getHeight() - 5);
		}
	    };
	    fPanel.setPreferredSize(new Dimension(25, 25));
	    fPanel.setBorder(BorderFactory.createLineBorder(Color.WHITE, 2));

	}
	return fPanel;
    }

    /**
     * @return
     */
    private PTextField getFirstField() {
	if (firstField == null) {
	    firstField = new PTextField(user.getFirstName(),TextFieldType.LONG);
	    firstField.setEditable(false);
	}
	return firstField;
    }

    /**
     * @return
     */
    private PButton getFirstEdit() {
	if (firstEdit == null) {
	    firstEdit = new PButton("edit",ButtonType.EDIT);
	    firstEdit.addActionListener(this);
	}
	return firstEdit;
    }

    /**
     * @return
     */
    private JPanel getLastPanel() {
	if (lastPanel == null) {
	    lastPanel = new JPanel();

	    lastPanel.setLayout(new BorderLayout());
	    lastPanel.setBorder(new EmptyBorder(10,10,0,10));

	    lastPanel.add(getLPanel(), BorderLayout.WEST);

	    JPanel centerPanel = new JPanel();
	    centerPanel.setLayout(new GridBagLayout());
	    GridBagConstraints gbc1 = new GridBagConstraints();
	    gbc1.anchor = GridBagConstraints.WEST;
	    gbc1.weightx = 1;
	    centerPanel.add(getLastField(), gbc1);
	    lastPanel.add(centerPanel, BorderLayout.CENTER);
	    
	    lastPanel.add(getLastEdit(), BorderLayout.EAST);
	}
	return lastPanel;
    }

    /**
     * @return
     */
    private JPanel getLPanel() {
	if (lPanel == null) {
	    lPanel = new JPanel() {
		private static final long serialVersionUID = 1L;

		public void paintComponent(Graphics g) {
		    super.paintComponent(g);
		    g.setColor(new Color(100, 150, 220));
		    g.fillRect(0, 0, getWidth(), getHeight());
		    g.setColor(Color.white);
		    g.setFont(new Font(Font.SANS_SERIF, Font.BOLD, 20));
		    g.drawString("l:", 5, getHeight() - 5);
		}
	    };
	    lPanel.setPreferredSize(new Dimension(25, 25));
	    lPanel.setBorder(BorderFactory.createLineBorder(Color.WHITE, 2));
	}
	return lPanel;
    }

    /**
     * @return
     */
    private PTextField getLastField() {
	if (lastField == null) {
	    lastField = new PTextField(user.getLastName(),TextFieldType.LONG);
	    lastField.setEditable(false);
	}
	return lastField;
    }

    /**
     * @return
     */
    private PButton getLastEdit() {
	if (lastEdit == null) {
	    lastEdit = new PButton("edit",ButtonType.EDIT);
	    lastEdit.addActionListener(this);
	}
	return lastEdit;
    }

    /**
     * @return
     */
    private JPanel getUserPanel() {
	if (userPanel == null) {
	    userPanel = new JPanel();

	    userPanel.setLayout(new BorderLayout());
	    userPanel.setBorder(new EmptyBorder(10,10,0,10));

	    userPanel.add(getUPanel(), BorderLayout.WEST);

	    JPanel centerPanel = new JPanel();
	    centerPanel.setLayout(new GridBagLayout());
	    GridBagConstraints gbc1 = new GridBagConstraints();
	    gbc1.anchor = GridBagConstraints.WEST;
	    gbc1.weightx = 1;
	    centerPanel.add(getUserField(), gbc1);
	    userPanel.add(centerPanel, BorderLayout.CENTER);

	    userPanel.add(getUserEdit(), BorderLayout.EAST);
	}
	return userPanel;
    }

    /**
     * @return
     */
    private JPanel getUPanel() {
	if (uPanel == null) {
	    uPanel = new JPanel() {
		/**
		 * 
		 */
		private static final long serialVersionUID = 1L;

		public void paintComponent(Graphics g) {
		    super.paintComponent(g);
		    g.setColor(new Color(100, 150, 220));
		    g.fillRect(0, 0, getWidth(), getHeight());
		    g.setColor(Color.white);
		    g.setFont(new Font(Font.SANS_SERIF, Font.BOLD, 20));
		    g.drawString("u:", 5, getHeight() - 5);
		}
	    };
	    uPanel.setPreferredSize(new Dimension(25, 25));
	    uPanel.setBorder(BorderFactory.createLineBorder(Color.WHITE, 2));
	}
	return uPanel;
    }

    /**
     * @return
     */
    private PTextField getUserField() {
	if (userField == null) {
	    userField = new PTextField(user.getUsername(),TextFieldType.LONG);
	    userField.setEditable(false);
	}
	return userField;
    }

    /**
     * @return
     */
    private PButton getUserEdit() {
	if (userEdit == null) {
	    userEdit = new PButton("edit",ButtonType.EDIT);
	    userEdit.addActionListener(this);
	}
	return userEdit;
    }

    /**
     * @return
     */
    private JPanel getEmailPanel() {
	if (emailPanel == null) {
	    emailPanel = new JPanel();

	    emailPanel.setLayout(new BorderLayout());
	    emailPanel.setBorder(new EmptyBorder(10,10,0,10));

	    emailPanel.add(getEPanel(), BorderLayout.WEST);

	    JPanel centerPanel = new JPanel();
	    centerPanel.setLayout(new GridBagLayout());
	    GridBagConstraints gbc1 = new GridBagConstraints();
	    gbc1.anchor = GridBagConstraints.WEST;
	    gbc1.weightx = 1;
	    centerPanel.add(getEmailField(), gbc1);
	    emailPanel.add(centerPanel, BorderLayout.CENTER);
	    
	    emailPanel.add(getEmailEdit(), BorderLayout.EAST);
	}
	return emailPanel;
    }

    /**
     * @return
     */
    private JPanel getEPanel() {
	if (ePanel == null) {
	    ePanel = new JPanel() {
		/**
		 * 
		 */
		private static final long serialVersionUID = 1L;

		public void paintComponent(Graphics g) {
		    super.paintComponent(g);
		    g.setColor(new Color(100, 150, 220));
		    g.fillRect(0, 0, getWidth(), getHeight());
		    g.setColor(Color.white);
		    g.setFont(new Font(Font.SANS_SERIF, Font.BOLD, 20));
		    g.drawString("e:", 5, getHeight() - 5);
		}
	    };
	    ePanel.setPreferredSize(new Dimension(25, 25));
	    ePanel.setBorder(BorderFactory.createLineBorder(Color.WHITE, 2));
	}
	return ePanel;
    }

    /**
     * @return
     */
    private PTextField getEmailField() {
	if (emailField == null) {
	    emailField = new PTextField(user.getEmail(),TextFieldType.LONG);
	    emailField.setEditable(false);
	}
	return emailField;
    }

    /**
     * @return
     */
    private PButton getEmailEdit() {
	if (emailEdit == null) {
	    emailEdit = new PButton("edit",ButtonType.EDIT);
	    emailEdit.addActionListener(this);
	}
	return emailEdit;
    }

    /**
     * @return
     */
    private JPanel getPhonePanel() {
	if (phonePanel == null) {
	    phonePanel = new JPanel();

	    phonePanel.setLayout(new BorderLayout());
	    phonePanel.setBorder(new EmptyBorder(10,10,0,10));

	    phonePanel.add(getPPanel(), BorderLayout.WEST);

	    JPanel centerPanel = new JPanel();
	    centerPanel.setLayout(new GridBagLayout());
	    GridBagConstraints gbc1 = new GridBagConstraints();
	    gbc1.anchor = GridBagConstraints.WEST;
	    gbc1.weightx = 1;
	    centerPanel.add(getPhoneField(), gbc1);
	    phonePanel.add(centerPanel, BorderLayout.CENTER);

	    phonePanel.add(getPhoneEdit(), BorderLayout.EAST);
	}
	return phonePanel;
    }

    /**
     * @return
     */
    private JPanel getPPanel() {
	if (pPanel == null) {
	    pPanel = new JPanel() {
		/**
		 * 
		 */
		private static final long serialVersionUID = 1L;

		public void paintComponent(Graphics g) {
		    super.paintComponent(g);
		    g.setColor(new Color(100, 150, 220));
		    g.fillRect(0, 0, getWidth(), getHeight());
		    g.setColor(Color.white);
		    g.setFont(new Font(Font.SANS_SERIF, Font.BOLD, 20));
		    g.drawString("p:", 5, getHeight() - 5);
		}
	    };
	    pPanel.setPreferredSize(new Dimension(25, 25));
	    pPanel.setBorder(BorderFactory.createLineBorder(Color.WHITE, 2));
	}
	return pPanel;
    }

    /**
     * @return
     */
    private PTextField getPhoneField() {
	if (phoneField == null) {
	    phoneField = new PTextField(Integer.toString(user.getCellPhone()),TextFieldType.LONG);
	    phoneField.setEditable(false);
	}
	return phoneField;
    }

    /**
     * @return
     */
    private PButton getPhoneEdit() {
	if (phoneEdit == null) {
	    phoneEdit = new PButton("edit",ButtonType.EDIT);
	    phoneEdit.addActionListener(this);
	}
	return phoneEdit;
    }

    /**
     * @return
     */
    private JPanel getAgePanel() {
	if (agePanel == null) {
	    agePanel = new JPanel();

	    agePanel.setLayout(new BorderLayout());
	    agePanel.setBorder(new EmptyBorder(10,10,10,10));

	    agePanel.add(getAPanel(), BorderLayout.WEST);

	    JPanel centerPanel = new JPanel();
	    centerPanel.setLayout(new GridBagLayout());
	    GridBagConstraints gbc1 = new GridBagConstraints();
	    gbc1.anchor = GridBagConstraints.WEST;
	    gbc1.weightx = 1;
	    centerPanel.add(getAgeField(), gbc1);
	    agePanel.add(centerPanel, BorderLayout.CENTER);

	    agePanel.add(getAgeEdit(), BorderLayout.EAST);
	}
	return agePanel;
    }

    /**
     * @return
     */
    private JPanel getAPanel() {
	if (aPanel == null) {
	    aPanel = new JPanel() {
		/**
		 * 
		 */
		private static final long serialVersionUID = 1L;

		public void paintComponent(Graphics g) {
		    super.paintComponent(g);
		    g.setColor(new Color(100, 150, 220));
		    g.fillRect(0, 0, getWidth(), getHeight());
		    g.setColor(Color.white);
		    g.setFont(new Font(Font.SANS_SERIF, Font.BOLD, 20));
		    g.drawString("a:", 5, getHeight() - 5);
		}
	    };
	    aPanel.setPreferredSize(new Dimension(25, 25));
	    aPanel.setBorder(BorderFactory.createLineBorder(Color.WHITE, 2));
	}
	return aPanel;
    }

    /**
     * @return
     */
    private PTextField getAgeField() {
	if (ageField == null) {
	    ageField = new PTextField(Integer.toString(user.getAge()),TextFieldType.LONG);
	    ageField.setEditable(false);
	}
	return ageField;
    }

    /**
     * @return
     */
    private PButton getAgeEdit() {
	if (ageEdit == null) {
	    ageEdit = new PButton("edit",ButtonType.EDIT);
	    ageEdit.addActionListener(this);
	}
	return ageEdit;
    }

    /**
     * @return
     */
    private JPanel getBottomPanel() {
	if (bottomPanel == null) {
	    bottomPanel = new JPanel();

	    bottomPanel.setLayout(new BorderLayout());

	    bottomPanel.add(getTitlePanel(), BorderLayout.NORTH);
	    bottomPanel.add(getAppointmentScrollPane(), BorderLayout.CENTER);
	    bottomPanel.add(getButtonPanel(),BorderLayout.SOUTH);
	}
	return bottomPanel;
    }

    /**
     * @return
     */
    private JPanel getTitlePanel() {
	if (titlePanel == null) {
	    titlePanel = new JPanel() {
		/**
		 * 
		 */
		private static final long serialVersionUID = 1L;

		public void paintComponent(Graphics g) {
		    super.paintComponent(g);
		    g.setColor(ProjectConstants.SUBHEADER_COLOR);
		    g.fillRect(0, 0, getWidth(), getHeight());
		    g.setColor(Color.white);
		    g.setFont(new Font(Font.SANS_SERIF, Font.BOLD, 12));
		    g.drawString("APPOINTMENTS:", 10, getHeight() - 5);
		}
	    };
	    titlePanel.setPreferredSize(new Dimension(WIDTH, 50));
	}
	return titlePanel;
    }

    /**
     * @return
     */
    private JScrollPane getAppointmentScrollPane() {
	if (appointmentScrollPane == null) {
	    appointmentScrollPane = new JScrollPane();
	    appointmentScrollPane.setPreferredSize(new Dimension(WIDTH, 100));
	    appointmentScrollPane.setViewportView(getAppointmentList());
	}
	return appointmentScrollPane;
    }

    /**
     * @return
     */
    private JList getAppointmentList() {
	if (appointmentList == null) {
	    appointmentList = new JList(new AppointmentListModel());
	    appointmentList.setCellRenderer(new AppointmentListRenderer());
	    appointmentList.addMouseListener(new DoubleClickListener(
		    appointmentList));
	}
	return appointmentList;
    }

    private JPanel getButtonPanel(){
	if(buttonPanel == null){
	    buttonPanel = new JPanel();
	    
	    buttonPanel.setBorder(new EmptyBorder(10,10,10,10));
	    
	    buttonPanel.add(getCloseButton());
	}
	return buttonPanel;
    }
    
    private PButton getCloseButton(){
	if(closeButton == null){
	    closeButton = new PButton("Close",ButtonType.MEDIUM);
	    closeButton.addActionListener(this);
	}
	return closeButton;
    }
    /**
     * 
     */
    private void refreshPanel() {
	appointmentList.updateUI();
	repaint();
    }

    /**
     * 
     */
    private void updatePersonalInformation() {
	try {
	    MainClient.getConnection().userSearch(user.getUsername());
	} catch (UserException e) {
	    e.printStackTrace();
	}
	PersonalInfo toSet = new PersonalInfo(user.getAccessLevel());
	toSet.setFirstName(getFirstField().getText());
	toSet.setLastName(getLastField().getText());
	toSet.setUsername(getUserField().getText());
	toSet.setEmail(getEmailField().getText());
	toSet.setCellPhone(Integer.parseInt(getPhoneField().getText()));
	toSet.setAge(Integer.parseInt(getAgeField().getText()));
	try {
	    MainClient.getConnection().setSearchPersonalInfo(toSet);
	} catch (UserException e) {
	    e.printStackTrace();
	}
    }

    /**
     * @author mramsey3
     * 
     */
    private class AppointmentListModel extends AbstractListModel {
	private static final long serialVersionUID = 1L;

	/*
	 * (non-Javadoc)
	 * 
	 * @see javax.swing.ListModel#getElementAt(int)
	 */
	public Object getElementAt(int i) {
	    ArrayList<Appointment> appointments = new ArrayList<Appointment>();
	    try {
		MainClient.getConnection().userSearch(user.getUsername());
		appointments = MainClient.getConnection()
			.getSearchUserAppointments();
	    } catch (UserException e) {
		e.printStackTrace();
	    }
	    return appointments.get(i);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see javax.swing.ListModel#getSize()
	 */
	public int getSize() {
	    ArrayList<Appointment> appointments = new ArrayList<Appointment>();
	    try {
		MainClient.getConnection().userSearch(user.getUsername());
		appointments = MainClient.getConnection()
			.getSearchUserAppointments();
	    } catch (UserException e) {
		e.printStackTrace();
	    }
	    return appointments.size();
	}
    }

    /**
     * @author mramsey3
     * 
     */
    private class DoubleClickListener extends MouseAdapter {
	protected JList list;

	/**
	 * @param l
	 */
	public DoubleClickListener(JList l) {
	    list = l;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * java.awt.event.MouseAdapter#mouseClicked(java.awt.event.MouseEvent)
	 */
	public void mouseClicked(MouseEvent e) {
	    if (e.getSource() == appointmentList)
		if (e.getClickCount() == 2) {
		    if (appointmentList.getModel().getSize() > 0) {
			int index = list.locationToIndex(e.getPoint());
			ListModel lm = list.getModel();
			Appointment a = (Appointment) (lm.getElementAt(index));
			ReportDialog report = new ReportDialog(a);
			report.setVisible(true);
			refreshPanel();
		    }
		}
	}
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
     */
    @Override
    public void actionPerformed(ActionEvent e) {
	if (e.getSource() == getFirstEdit()) {
	    String newFirstName = JOptionPane.showInputDialog("First name:");
	    getFirstField().setText(newFirstName);
	    updatePersonalInformation();
	} else if (e.getSource() == getLastEdit()) {
	    String newLastName = JOptionPane.showInputDialog("Last Name:");
	    getLastField().setText(newLastName);
	    updatePersonalInformation();
	} else if (e.getSource() == getUserEdit()) {
	    String newUsername = JOptionPane.showInputDialog("Username:");
	    getUserField().setText(newUsername);
	    updatePersonalInformation();
	} else if (e.getSource() == getEmailEdit()) {
	    String newEmail = JOptionPane.showInputDialog("Email:");
	    getEmailField().setText(newEmail);
	    updatePersonalInformation();
	} else if (e.getSource() == getPhoneEdit()) {
	    String newPhone = JOptionPane.showInputDialog("Phone:");
	    getPhoneField().setText(newPhone);
	    updatePersonalInformation();
	} else if (e.getSource() == getAgeEdit()) {
	    String newAge = JOptionPane.showInputDialog("Age:");
	    getAgeField().setText(newAge);
	    updatePersonalInformation();
	} else if(e.getSource() == getCloseButton()) {
	    this.setVisible(false);
	}
    }
}
